<template>
  <div class="main-layout-1">
    <div id="map" ref="map"></div>
    <div>
      <input id="radius" type="range" min="1" max="50" step="1" value="5"/>
      <input id="blur" type="range" min="1" max="50" step="1" value="15"/>
      <button @click="removeHeatLayer">隐藏热力图</button>
      <button @click="addHeatLayer">显示热力图</button>

      <div id="overlay-box"></div>
    </div>
  </div>
</template>

<script>
  import 'ol/ol.css';
  import { Map, View, Feature, Overlay } from 'ol'
  import KML from 'ol/format/KML';
  // import VectorSource from 'ol/source/Vector';
  // import OSM from 'ol/source/OSM'
  import { OSM, Vector as VectorSource, Cluster } from 'ol/source'
  import { fromLonLat, toLonLat, transform } from 'ol/proj'
  import { Heatmap as HeatmapLayer, Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
  import { Point, MultiPolygon, Polygon, LineString } from 'ol/geom'
  import { Style, Fill, Stroke, Circle as CircleStyle, Text, Icon } from 'ol/style'

  import sichuanOutside from '/@/source/sichuanOutside.json'
  import trackCar from '/@/source/track-car.json'

  export default {
    name: 'heatmap',
    data () {
      return {

      }
    },
    mounted () {
      this.initMap()
      // this.addVector(sichuanOutside) // 添加行政区划轮廓
      // this.addHeatMap() // 添加热力图
      // this.addCluster() // 添加聚合
      // this.addEvent() // 添加事件
      // this.addTrack() // 添加行车路线（包括起始位置和终止位置）
      this.drawArea()

      this.createHeatLayer()
      this.addHeatLayer()
    },
    methods: {
      initMap () {
        let target = "map"; //跟页面元素的 id 绑定来进行渲染
        let tileLayers = [
          new TileLayer({
            source: new OSM()
          }),
        ];
        const view = new View({
          center: fromLonLat([104.912777, 34.730746]), //地图中心坐标
          zoom: 4.5 //缩放级别
        });
        this.map = new Map({
          target: target, //绑定dom元素进行渲染
          layers: tileLayers, //配置地图数据源
          view, //配置地图显示的options配置（坐标系，中心点，缩放级别等）
        });
      },
      addEvent () {
        this.map.on('singleclick', e => {
          const coordinate = e.coordinate
          // const coordinate = toLonLat(e.coordinate)
          // const coordinate = transform(e.coordinate, 'EPSG:3857', 'EPSG:4326')
          this.addPoint(coordinate) // 根据给定坐标（此处是单击的点）添加标记
        })
      },
      addPoint (coordinate) {
        console.log(coordinate)
        this.pointLayer = new VectorLayer({
          source: new VectorSource()
        })
        this.map.addLayer(this.pointLayer)

        const feature = new Feature({
          geometry: new Point(coordinate)
        })
        feature.setStyle(this.getIcon())
        this.pointLayer.getSource().addFeature(feature)

        this.addText(coordinate)
      },
      getIcon () {
        return new Style({
          image: new Icon({
            src: 'source/marker.png',
            anchor: [0.5, 1],
            // color: 'red',
            // scale: 0.75
          }),
          // text: new Text({
          //   text: '标记',
          //   font: '14px',
          //   fill: new Fill({
          //     color: 'blue',
          //   }),
          //   offsetY: 10,
          // })
        })
      },
      addText (coordition) {
        const overlayBox = document.getElementById('overlay-box')
        const oDiv = document.createElement('span')
        oDiv.contentEditable = true
        oDiv.id = coordition[0]
        const pText = document.createTextNode('摄像头')
        oDiv.appendChild(pText)
        overlayBox.appendChild(oDiv)
        const textInfo = new Overlay({
          position: coordition,
          element: document.getElementById(coordition[0]),
          offset: [-24, 0],
        })
        this.map.addOverlay(textInfo)
      },
      addTrack () {
        const routeFeature = new Feature({
          type: 'route',
          geometry: new LineString(trackCar).transform('EPSG:4326', 'EPSG:3857')
        })
        const startMarker = new Feature({
          type: 'startMarker',
          geometry: new Point(trackCar[0]).transform('EPSG:4326', 'EPSG:3857')
        })
        const endMarker = new Feature({
          type: 'endMarker',
          geometry: new Point(trackCar[trackCar.length - 1]).transform('EPSG:4326', 'EPSG:3857')
        })
        const style = {
          route: new Style({
            stroke: new Stroke({
              width: 3,
              color: 'red',
            })
          }),
          startMarker: new Style({
            image: new Icon({
              src: 'source/marker.png',
              anchor: [0.5, 1],
              color: 'pink'
            })
          }),
          endMarker: new Style({
            image: new Icon({
              src: 'source/marker.png',
              anchor: [0.5, 1],
              color: 'yellow'
            })
          }),
        }
        const source = new VectorSource({
          features: [routeFeature, startMarker, endMarker],
        })
        this.carLineStringLayer = new VectorLayer({
          source,
          style (feature) {
            return style[feature.get('type')]
          },
        })

        this.map.addLayer(this.carLineStringLayer)

        this.map.getView().fit(source.getExtent())
      },
      addVector (areaGeo) {
        let routeFeature = []
        areaGeo.forEach(g => {
          let geometry
          let lineData = g.features[0]
          if (lineData.geometry.type === 'MultiPolygon') {
            geometry = new MultiPolygon(
              lineData.geometry.coordinates
            )
          } else {
            geometry = new Polygon(
              lineData.geometry.coordinates
            )
          }
          geometry = geometry.transform('EPSG:4326', 'EPSG:3857')
          this.gometry = geometry
          routeFeature = new Feature({
            geometry,
          });
        })
        routeFeature.setStyle(new Style({
          fill: new Fill({
            color: [71, 137, 227, 0.3],
          }),
          stroke: new Stroke({
            width: 1,
            color: [71, 137, 227, 1],
          })
        }))
        const routeLayer = new VectorLayer({
          source: new VectorSource({
            features: [
              routeFeature,
            ],
          })
        })
        this.map.addLayer(routeLayer)

        this.map.getView().fit(this.gometry, {
          padding: [20, 20, 20, 20],
        })
      },
      addHeatMap() {
        let hatmapData = [
          { name: "成都市" },
          { name: "成都市" },
          { name: "成都市" },
          { name: "成都市" },
          { name: "绵阳市" },
          { name: "广安市" },
          { name: "雅安市" },
          { name: "自贡市" },
          { name: "自贡市" },
          { name: "自贡市" },
          { name: "自贡市" },
          { name: "自贡市" },
          { name: "自贡市" },
          { name: "自贡市" },
          { name: "宜宾市" },
          { name: "甘孜藏族自治州市" }
        ];
        let colors = [
          "#2200FF",
          "#16D9CC",
          "#4DEE12",
          "#E8D225",
          "#EF1616"
        ];
        let codeList = {
          成都市: { center: { lng: 104.061902, lat: 30.609503 } },
          广安市: { center: { lng: 106.619126, lat: 30.474142 } },
          绵阳市: { center: { lng: 104.673612, lat: 31.492565 } },
          雅安市: { center: { lng: 103.031653, lat: 30.018895 } },
          自贡市: { center: { lng: 104.797794, lat: 29.368322 } },
          宜宾市: { center: { lng: 104.610964, lat: 28.781347 } },
          甘孜藏族自治州市: { center: { lng: 101.592433, lat: 30.426712 } },
        };
        this.heatLayer = new HeatmapLayer({
          source: new VectorSource(),
          blur: 30,
          radius: 15,
          gradient: colors
        });
        this.map.addLayer(this.heatLayer);
        this.AppendFeatures(hatmapData, colors, codeList, 50);
      },
      AppendFeatures(hatmapData, colors, points, max) {
        this.max = max
        const features = []
        hatmapData.map((item) => {
          const coordInfo = points[item.name]
          if (coordInfo) {
            const feature = new Feature({
              geometry: new Point(fromLonLat([coordInfo.center.lng, coordInfo.center.lat]))
            })
            features.push(feature)
          }
        })

        this.heatLayer.getSource().addFeatures(features);
      },
      createHeatLayer () {
        const blur = document.getElementById('blur')
        const radius = document.getElementById('radius')

        this.globalHateLayer = new HeatmapLayer({
          source: new VectorSource({
            url: '/source/2012_Earthquakes_Mag5.kml',
            format: new KML({
              extractStyles: false
            })
          }),
          blur: parseInt(blur.value, 10),
          radius: parseInt(radius.value, 10),
          weight: function(feature) {
            var name = feature.get('name');
            var magnitude = parseFloat(name.substr(2));
            return magnitude - 5;
          },
        });
      },
      removeHeatLayer () {
        // this.globalHateLayer.getSource().clear()
        this.map.removeLayer(this.globalHateLayer)
        this.globalHateLayer.getSource().changed()
      },
      addHeatLayer () {
        this.map.addLayer(this.globalHateLayer)
        // this.globalHateLayer.getSource().changed()
      },
      addCluster () {
        let clusterData = [
          { name: "成都市", value: 85, center: { lng: 104.061902, lat: 30.609503 } },
          { name: "绵阳市", value: 36, center: { lng: 106.619126, lat: 30.474142 } },
          { name: "广安市", value: 50, center: { lng: 104.673612, lat: 31.492565 } },
          { name: "雅安市", value: 555, center: { lng: 103.031653, lat: 30.018895 } },
          { name: "自贡市", value: 55, center: { lng: 104.797794, lat: 29.368322 } },
          { name: "宜宾市", value: 666, center: { lng: 104.610964, lat: 28.781347 } },
          { name: "内江市", value: 777, center: { lng: 105.064555, lat: 29.581632 } },
        ];

        // 实现聚合分散方法
        // this.addCluster(clusterData, points, true);
        let layer = new VectorLayer({
          source: new Cluster({
            distance: parseInt(20, 10),
            source: new VectorSource(),
          }),
          style: this.clusterStyle.call(this)
        })
        this.map.addLayer(layer)

        const features = []
        clusterData.forEach(item => {
          const { name, value, center: { lng, lat }} = item
          let point = new Feature({
            geometry: new Point(fromLonLat([lng, lat])),
          })
          point.set('name', name)
          point.set('value', value)
          features.push(point)
        })
        console.log(features)
        layer.getSource().getSource().addFeatures(features)
      },
      clusterStyle () {
        return (feature, solution) => {
          let total = 0
          feature.get('features').forEach((item) => {
            total += item.get('value')
          })
          const style = new Style({
            image: new CircleStyle({
              radius: 15,
              stroke: new Stroke({
                color: 'blue',
              }),
              fill: new Fill({
                color: 'rgba(24, 144, 255, 1)'
              })
            }),
            text: new Text({
              text: total.toString(),
              fill: new Fill({
                color: '#fff',
              })
            })
          })
          return style
        }
      },
      drawArea () {

      },
    },
  }
</script>
<style lang="scss" scoped>
  #map {
    width: 100%;
    height: 100%;
  }
</style>
